<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace App\Controller;

use App\Services\ClientUserService;
use App\Services\RoomManager;
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
use Swoole\Http\Request;
use Swoole\Websocket\Frame;

class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
{
    protected $clientUserService;

    protected $roomManager;

    public function __construct()
    {
        $this->clientUserService = ClientUserService::getInstance();
        $this->roomManager = RoomManager::getIns();
    }

    public function onMessage($server, Frame $frame): void
    {
        $server->push($frame->fd, 'Recv: ' . $frame->data);
        $user_id = json_decode($frame->data, true)['user_id'];

        if (! $this->clientUserService->checkBind($user_id)) {
            $this->clientUserService->bind($user_id, $frame->fd);
        }
        $this->roomManager->setNewRoom('room_01');
        $this->roomManager->joinRoom($user_id, 'room_01', 'player');
    }

    public function onClose($server, int $fd, int $reactorId): void
    {
        // 感觉会有并发问题
        // 同一 FD 断开和链接同时进来的话...
        // 只删除 USER-FD 不删除 FD-USER?
        // 断开的时候不删除房间内的 player 这样在断线重链接的时候 可以重新接入...
        // 那么解除绑定就要分好多种情况了...比如干净断开 各种掉线 有的需要清除房间内信息 有的需要保留 有的...
        $this->clientUserService->unbind($fd);
        var_dump('closed');
    }

    public function onOpen($server, Request $request): void
    {
        $server->push($request->fd, 'Opened');
    }
}
